package com.shareroad.dubboweb.frame.util;

import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shareroad.dubboweb.client.annotation.DubboParam;
import com.shareroad.dubboweb.client.annotation.DubboWeb;
import com.shareroad.dubboweb.frame.dao.po.DubboInterfacePO;
import com.shareroad.dubboweb.frame.dao.po.DubboMethodPO;
import com.shareroad.dubboweb.frame.dao.po.DubboParamPO;
import com.shareroad.dubboweb.frame.dao.po.DubboWebPO;
import com.shareroad.dubboweb.frame.model.enums.ErrorCode;

public class JarUtil {
	
	@SuppressWarnings("resource")
	public static DubboWebPO parseJar(String jarPath){
		JarFile jarFile = null;
		DubboWebPO dubboWebPO = new DubboWebPO();
		try{
			File file = new File(jarPath);
			dubboWebPO.jarName = file.getName();  
			jarFile = new JarFile(file);//读入jar文件 
			List<DubboInterfacePO> interfaceList = new ArrayList<DubboInterfacePO>();
			URLClassLoader loader = new URLClassLoader(new URL[] { file.toURL() });
			Enumeration<JarEntry> en = jarFile.entries(); // 枚举获得JAR文件内的实体,即相对路径
			while (en.hasMoreElements()) { // 遍历显示JAR文件中的内容信息
				try {
					JarEntry jentry = en.nextElement(); // 调用方法显示内容
					if(!jentry.getName().endsWith(".class")){
						continue;
					}
					String clazzPath = jentry.getName().replace("/", ".").replace(".class", "");
					Class<?> cl = loader.loadClass(clazzPath);
					DubboWeb interfaceAnno = (DubboWeb) cl.getAnnotation(DubboWeb.class);
					if(!cl.isInterface() || null == interfaceAnno){
						continue;
					}
					DubboInterfacePO dubboInterface = new DubboInterfacePO();
					dubboInterface.packageName = cl.getPackage().getName();
					dubboInterface.interfaceName = cl.getSimpleName();
					List<DubboMethodPO> methodList = new ArrayList<DubboMethodPO>();
					Method[] methods = cl.getDeclaredMethods();
					for (Method mth : methods) {
						DubboMethodPO dubboMethod = new DubboMethodPO();
						dubboMethod.returnType = mth.getReturnType().getSimpleName();
						dubboMethod.methodName = mth.getName();
						List<DubboParamPO> paramList = new ArrayList<DubboParamPO>();
						Parameter[] params = mth.getParameters();
						for (Parameter param : params) {
							DubboParamPO dubboParam = new DubboParamPO();
							DubboParam paramAnno = param.getAnnotation(DubboParam.class);
							if (null != paramAnno) {
								dubboParam.name = paramAnno.name();
								dubboParam.desc = paramAnno.desc();
							}
							dubboParam.type = param.getType().getSimpleName();
							paramList.add(dubboParam);
						}
						dubboMethod.dubboParamList = paramList;
						methodList.add(dubboMethod);
					}
					dubboInterface.dubboMethodList = methodList;
					interfaceList.add(dubboInterface);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			dubboWebPO.dubboInterfaceList = interfaceList;
		}catch(Exception e){
			e.printStackTrace();
			dubboWebPO.errorCode = ErrorCode.api_parse_jar_error.getCode();
			dubboWebPO.errorDesc = ErrorCode.api_parse_jar_error.getDesc();
		}finally{
			try {
				jarFile.close();
			} catch (Exception e) {
				e.printStackTrace();
			}  
		}
		return dubboWebPO;
	}
	
	public static void main(String[] args){
		String path = "D:/api/";
		File file = new File(path);
		for(File f : file.listFiles()){
			System.out.println(f.getPath());
			System.out.println(JSONObject.toJSONString(JarUtil.parseJar(f.getPath())));
		}
	}
	
}
